package tech.lq0.dreamaticvoyage.voyage;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraftforge.common.crafting.conditions.ICondition;
import net.minecraftforge.event.AddReloadListenerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import tech.lq0.dreamaticvoyage.Utils;
import tech.lq0.dreamaticvoyage.voyage.core.VoyageEvent;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE)
public class VoyageEventManager extends SimpleJsonResourceReloadListener {

    private static final Map<ResourceLocation, VoyageEvent> EVENTS = new HashMap<>();

    private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
    private ICondition.IContext ctx = ICondition.IContext.EMPTY;
    public static final String PATH = "voyage_events";

    public static VoyageEventManager INSTANCE = new VoyageEventManager();

    public VoyageEventManager() {
        super(GSON, PATH);
    }

    public VoyageEventManager(ICondition.IContext ctx) {
        this();
        this.ctx = ctx;
    }

    @SubscribeEvent
    public static void onAddReloadListeners(AddReloadListenerEvent event) {
        ICondition.IContext ctx = event.getConditionContext();
        VoyageEventManager.INSTANCE = new VoyageEventManager(ctx);
        event.addListener(VoyageEventManager.INSTANCE);
    }

    @Override
    protected void apply(Map<ResourceLocation, JsonElement> pObject, ResourceManager pResourceManager, ProfilerFiller pProfiler) {
        Map<ResourceLocation, JsonElement> sorted = new LinkedHashMap<>();

        pResourceManager.listPacks().forEach(packResources -> {
            Set<String> namespaces = packResources.getNamespaces(PackType.SERVER_DATA);
            namespaces.forEach(
                    namespace -> packResources.listResources(PackType.SERVER_DATA, namespace, PATH,
                            (resourceLocation, inputStreamIoSupplier) -> {
                                String path = resourceLocation.getPath();
                                ResourceLocation rl = new ResourceLocation(namespace,
                                        path.substring((PATH + "/").length(), path.length() - ".json".length()));

                                JsonElement el = pObject.get(rl);
                                if (el != null) {
                                    sorted.put(rl, el);
                                }
                            }
                    )
            );
        });

        for (Map.Entry<ResourceLocation, JsonElement> entry : sorted.entrySet()) {
            ResourceLocation location = entry.getKey();
            JsonElement element = entry.getValue();

            try {
                // 读取并解析JSON
                VoyageEvent event = VoyageEvent.createFromJson(location, element.getAsJsonObject());
                VoyageEventManager.register(location, event);
            } catch (Exception e) {
                Utils.LOGGER.error("Failed to load voyage event: {}", location, e);
            }
        }
    }

    public static void clear() {
        EVENTS.clear();
    }

    public static void register(ResourceLocation id, VoyageEvent event) {
        Utils.LOGGER.info("Registering voyage event: {}", id);
        EVENTS.put(id, event);
    }

    public static VoyageEvent get(ResourceLocation id) {
        return EVENTS.get(id);
    }
}
